package com.jjy.ideaplugin;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;

public class JumpToLineAction extends AnAction {

    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        Project project = e.getProject();
        if (project == null) {
            return;
        }

        Editor editor = e.getDataContext().getData(com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR);
        if (editor == null) {
            return;
        }

        int totalLines = editor.getDocument().getLineCount();

        LineNumberDialog dialog = new LineNumberDialog(totalLines);
        dialog.show();
        if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
            int lineNumber = dialog.getLineNumber();
            if (lineNumber > 0 && lineNumber <= totalLines) {
                editor.getCaretModel().moveToLogicalPosition(editor.offsetToLogicalPosition(editor.getDocument().getLineStartOffset(lineNumber - 1)));
                editor.getScrollingModel().scrollToCaret(ScrollType.CENTER_UP);
            } else {
                Messages.showWarningDialog(project, "Invalid line number", "Jump to Line");
            }
        }
    }

    private static class LineNumberDialog extends DialogWrapper {
        private int lineNumber;

        protected LineNumberDialog(int totalLines) {
            super(true);
            setTitle("Jump to Line");
            setResizable(false);

            lineNumber = totalLines / 2 + 1;

            init();
        }

        @Nullable
        @Override
        protected JComponent createCenterPanel() {
            JPanel panel = new JPanel(new BorderLayout());
            JLabel label = new JLabel("Line number:");
            JTextField textField = new JTextField(Integer.toString(lineNumber));

            panel.add(label, BorderLayout.WEST);
            panel.add(textField, BorderLayout.CENTER);

            textField.getDocument().addDocumentListener(new DocumentListener() {
                @Override
                public void insertUpdate(DocumentEvent e) {
                    validateLineNumber(textField);
                }

                @Override
                public void removeUpdate(DocumentEvent e) {
                    validateLineNumber(textField);
                }

                @Override
                public void changedUpdate(DocumentEvent e) {
                    validateLineNumber(textField);
                }

                private void validateLineNumber(JTextField textField) {
                    try {
                        lineNumber = Integer.parseInt(textField.getText());
                        setOKActionEnabled(lineNumber > 0);
                    }
                    catch (NumberFormatException e) {
                        setOKActionEnabled(false);
                    }
                }
            });

            return panel;
        }

        public int getLineNumber() {
            return lineNumber;
        }
    }
}